`timescale 1ns/1ns
`include "../verilog/counter.v"
`include "../verilog/top.v"

module top_tb;

reg clk;
reg reset;
reg [2:0] apply;
reg [2:0] inject;
reg [2:0] mode;
wire [1:0] led;
reg [1:0] old;

integer file;
integer toggles;

initial begin
	toggles <= 0;
	file = $fopen("../toggles.txt", "w");

	$dumpfile("top.vcd");
	$dumpvars(0, top);

	// initial values
	reset <= 1'b1;
	old <= 2'b10;
	apply <= 3'b000;
	inject <= 3'b000;
	mode <= 3'b000;

	// after some time release reset
	#200
	reset <= 1'b0;

	// begin
	@(posedge clk);
	while (toggles < 100) begin
		// wait for clk
		@(posedge clk)

		if (led != old) begin
			toggles <= toggles + 1;
			$display("@%2d: toggle to %1d\n", $time, led);
			$fwrite(file, "@%2d: toggle to %1d\n", $time, led);
		end
		old <= led;

		// inject faults
		if (toggles == 23) begin
			// inject xor fault
			apply[0] <= 1'b1;
			inject[0] <= 1'b1;
			mode[0] <= 1'b0;
		end else if (toggles == 26) begin
			// restore fault at 0
			apply[0] <= 1'b1;
			inject[0] <= 1'b0;
			mode[0] <= 1'b0;
		end else if (toggles == 27) begin
			// inject stuck at 1 fault
			apply[1] <= 1'b1;
			inject[1] <= 1'b0;
			mode[1] <= 1'b1;
		// remove faults
		end else if (toggles == 30) begin
			apply <= 3'b000;
			inject <= 3'b000;
			mode <= 3'b000;
		end
	end

	$fclose(file);  
	$display("test complete");
	$finish;
end

initial begin
	clk <= 1'b0;
	// wait 10ns for freq of 100 MHz
	forever #10 clk <= ~clk;
end

top #(.CYCLES_SEC (10)) top_inst (
	.clk(clk),
	.reset(reset),
	.apply(apply),
	.inject(inject),
	.mode(mode),
	.led(led)
);

endmodule
